#include "mainwindow.h"
#include "protocol.h"
#include "setting.h"
#include "aboutdialog.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QHostAddress>
#include <QHostInfo>
#include <QNetworkInterface>
#include <QTimer>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_isClient=false;
    initStatusbar();
    if(Setting::Instance().config.getBool(JSNAME(Setting::IsClient)))
    {
        ui->clientRadio->setChecked(true);
        on_clientRadio_clicked();
    }
    else
    {
        ui->serverRadio->setChecked(true);
    }

    m_model = new QStringListModel;
    ui->listView->setModel(m_model);
    ui->listView->setUpdatesEnabled(true);

    m_Name = QHostInfo::localHostName();
    initUI();

    if(!Setting::Instance().config.getBool(JSNAME(Setting::ShowLeft)))
    {
        ui->actionNet->setChecked(false);
        ui->groupBoxClient->hide();
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initUI()
{    
    QStringList ipList;
    if(getIP(ipList) > 0)
    {
        ui->ipComboBox->addItems(ipList);
    }

    ui->fontSlider->setValue(50);
    on_fontSlider_sliderMoved(50);

    m_timer = new QTimer();
    m_timer->setInterval(2);
    connect( m_timer, SIGNAL(timeout()), this, SLOT(handle_timeout()) );
    //connect( &tc, SIGNAL(timeout()), this, SLOT(handle_timeout()) );

    connect(&m_client,SIGNAL(processMsg(QString,QString,QString,qint64)),SLOT(handle_processClientMsg(QString,QString,QString,qint64)));
    connect(&m_server,SIGNAL(upClient(int,QString,QString)),SLOT(handle_upClient(int,QString,QString)));
}

void MainWindow::initStatusbar()
{
    for(int i=0;i<ST_COUNT;i++)
    {
        m_statusLabel[i] = new QLabel(this);
        m_statusLabel[i]->setStyleSheet("QLabel{ color: red }");

        statusBar()->addWidget(m_statusLabel[i]);
    }

    m_statusLabel[ST_SRVTYPE]->setText(tr("服务端"));
    m_statusLabel[ST_CONNECT]->setText(tr("未启动"));
}

void MainWindow::insertList(const QString &ip,const QString &name)
{
    QModelIndex index;
    QVariant variant;
    QString listIp;
    QString fixIp = "("+ip+")";
    int count=m_model->rowCount();

    for(int i=0;i<count;i++)
    {
        index=m_model->index(i,0);

        variant = m_model->data(index, Qt::DisplayRole);  //获取当前选择的项的文本
        listIp = variant.toString();
        if(listIp.indexOf(fixIp) > 0)
        {
            //modify
            m_model->setData(index,name+fixIp);
            return;
        }
    }

    //insert
    m_model->insertRows(count, 1);
    index = m_model->index(count,0);
    m_model->setData(index, name+fixIp);

}

void MainWindow::removeList(const QString &ip)
{
    QModelIndex index;
    QVariant variant;
    QString listIp;
    QString fixIp = "("+ip+")";
    int count=m_model->rowCount();
    for(int i=0;i<count;i++)
    {
        index=m_model->index(i,0);

        variant = m_model->data(index, Qt::DisplayRole);  //获取当前选择的项的文本
        listIp = variant.toString();
        if(listIp.indexOf(fixIp) > 0)
        {
            m_model->removeRows(i, 1);
            return;
        }
    }
}

//获取本机IP
int MainWindow::getIP(QStringList &ipList)
{
    int count=0;

    QString localHost = QHostInfo::localHostName();
    QHostInfo info = QHostInfo::fromName(localHost);
    info.addresses();//QHostInfo的address函数获取本机ip地址

    //如果存在多条ip地址ipv4和ipv6：
    foreach(QHostAddress address,info.addresses())
    {
        if(address.protocol()==QAbstractSocket::IPv4Protocol)
        {
            //只取ipv4协议的地址
            ipList<<address.toString();
            count++;
        }
    }

    return count;
}

QString MainWindow::getLocalMachineName()
{
    m_Name = QHostInfo::localHostName();
    return m_Name;
}

void MainWindow::handle_upClient(int type,const QString &name, const QString &ip)
{
    //up to listview
    switch (type) {
    case TimerServer::CLI_NEW:
        insertList(ip,name);
        break;
    case TimerServer::CLI_MODIFY:        
        insertList(ip,name);
        break;
    case TimerServer::CLI_REMOVE:
        removeList(ip);
        break;
    case TimerServer::ERR_MSG:
        QMessageBox::information(this, ip+"警告",name);
        return;
    default:
        return;
    }

    //up to status bar
    m_statusLabel[ST_CLIENT_COUNT]->setText("客户端数量:"+QString::number(m_server.clientNumber()));
}

void MainWindow::handle_processClientMsg(const QString &name, const QString &head, const QString &content,qint64 diffTime)
{
    Q_UNUSED(name)

    if(head == kTimerCmdSync)
    {
        uint32_t msec= content.toUInt();
        msec += diffTime;

        QString tmString,msecString;

        TimeCacle::Format(tmString,msecString,msec);
        ui->labelMain->setText(tmString);
        ui->labelMSec->setText(msecString);
        qDebug()<< content;
    }
    else if(head == kTimerCmdRegister)
    {
        //连接成功
        m_statusLabel[ST_CONNECT]->setText(tr("连接成功"));
        ui->startButton->setText(tr("关闭"));
    }
    else if(head == kTimerCmdControl)
    {
        if(content == "start")
        {
            m_timer->start();
            ui->actionStart->setText(tr("暂停"));
            ui->actionStart->setIcon(QIcon(":images/Kombine_toolbar_004.png"));
            tc.Resum(diffTime);
        }
        else if(content == "stop")
        {
            tc.Stop();
            m_timer->stop();
            ui->actionStart->setText(tr("开始"));
            ui->actionStart->setIcon(QIcon(":images/Kombine_toolbar_005.png"));
        }
        else if(content == "refresh")
        {
            on_actionRefresh_triggered();
        }
    }
}

void MainWindow::handle_timeout()
{
    QString tms,msec;
    uint32_t umsec=tc.GetTimeString(tms,msec);
    //qDebug()<<"time="<<tms;
    ui->labelMain->setText(tms);
    ui->labelMSec->setText(msec);
    if(!m_isClient && Setting::Instance().syncMode == Setting::SM_FULL)
    {
        m_server.Broadcast(m_Name,kTimerCmdSync,QString::number(umsec));
    }
}

void MainWindow::on_fontSlider_sliderMoved(int position)
{
    int pointSize = position*2+50;
    QFont font = ui->labelMain->font();
    font.setPointSize(pointSize);
    ui->labelMain->setFont(font);
    font.setPointSize(pointSize-10);
    ui->labelMSec->setFont(font);
    qDebug()<<position;
}

void MainWindow::on_actionNet_triggered()
{
    if(ui->actionNet->isChecked())
    {
        ui->groupBoxClient->show();
        Setting::Instance().config.setBool(JSNAME(Setting::ShowLeft),true);
    }
    else
    {
        ui->groupBoxClient->hide();
        Setting::Instance().config.setBool(JSNAME(Setting::ShowLeft),false);
    }
}

void MainWindow::on_actionOption_triggered()
{

}

void MainWindow::on_actionRefresh_triggered()
{
    if(tc.isStarted())
    {
        tc.Stop();
        m_timer->start();
        ui->actionStart->setText(tr("暂停"));
        ui->actionStart->setIcon(QIcon(":images/Kombine_toolbar_004.png"));
        tc.Start();
    }
    else
    {
        tc.reInit();
        QString tms,msec;
        tc.GetTimeString(tms,msec);
        //qDebug()<<"time="<<tms.c_str();
        ui->labelMain->setText(tms);
        ui->labelMSec->setText(msec);        
    }

    if(Setting::Instance().syncMode == Setting::SM_SHORT && !m_isClient)
    {
        m_server.Broadcast(m_Name,kTimerCmdControl,"refresh");
    }
}

void MainWindow::on_actionStart_triggered()
{
    if(ui->actionStart->text() == tr("开始"))
    {
        m_timer->start();
        if(Setting::Instance().syncMode == Setting::SM_SHORT && !m_isClient)
        {
            m_server.Broadcast(m_Name,kTimerCmdControl,"start");
        }
        ui->actionStart->setText(tr("暂停"));
        ui->actionStart->setIcon(QIcon(":images/Kombine_toolbar_004.png"));
        tc.Resum();
    }
    else
    {
        tc.Stop();
        if(Setting::Instance().syncMode == Setting::SM_SHORT && !m_isClient)
        {
            m_server.Broadcast(m_Name,kTimerCmdControl,"stop");
        }
        m_timer->stop();
        ui->actionStart->setText(tr("开始"));
        ui->actionStart->setIcon(QIcon(":images/Kombine_toolbar_005.png"));
    }
}

void MainWindow::on_actionQuit_triggered()
{
    QApplication::quit();
}

void MainWindow::on_actionAbout_triggered()
{
    AboutDialog dlg;
    dlg.exec();
}

void MainWindow::on_startButton_clicked()
{
    qDebug()<<m_isClient;
    if(m_isClient)
    {
        if(m_client.isConnect())
        {
            m_client.Disconnect();
            m_statusLabel[ST_CONNECT]->setText(tr("未连接"));
            ui->startButton->setText(tr("连接"));
        }
        else
        {
            QString ipStr= ui->ipComboBox->currentText();
            if(ipStr.isEmpty())
            {
                //
                QMessageBox::information(this, "警告","服务端IP不能为空");
            }
            else
            {
                m_client.Connect(ipStr,kTimerPort);
                m_client.SetName(getLocalMachineName());
                m_statusLabel[ST_CONNECT]->setText(tr("正在连接"));
                Setting::Instance().config.setParam(JSNAME(Setting::ServerIp),ipStr);
            }
        }
    }
    else
    {
        if(m_server.isStart())
        {
            m_server.Stop();
            if(!m_server.isStart())
            {
                ui->startButton->setText(tr("启动"));
                m_statusLabel[ST_CONNECT]->setText(tr("未启动"));
            }
        }
        else
        {
            if(m_server.Start())
            {
                m_statusLabel[ST_CONNECT]->setText(tr("已启动"));
                ui->startButton->setText(tr("停止"));
            }
            else
            {
                m_statusLabel[ST_CONNECT]->setText(tr("启动失败"));
            }
        }
    }
}

void MainWindow::on_serverRadio_clicked()
{
    if(ui->serverRadio->isChecked())
    {
        Setting::Instance().config.setBool(JSNAME(Setting::IsClient),false);

        ui->startButton->setText(tr("开启"));
        QStringList ipList;
        if(getIP(ipList) > 0)
        {
            ui->ipComboBox->addItems(ipList);
            ui->ipComboBox->setEditable(false);
        }
        else
        {
            ui->ipComboBox->setEditable(true);
        }

        m_isClient=false;
        m_statusLabel[ST_SRVTYPE]->setText(tr("服务端"));
    }
}

void MainWindow::on_clientRadio_clicked()
{
    if(ui->clientRadio->isChecked())
    {
        Setting::Instance().config.setBool(JSNAME(Setting::IsClient),true);

        ui->startButton->setText(tr("连接"));
        ui->ipComboBox->clear();
        ui->ipComboBox->setEditable(true);
        m_isClient=true;
        m_statusLabel[ST_SRVTYPE]->setText(tr("客户端"));

        m_statusLabel[ST_CLIENT_COUNT]->setText("");
        QString serverIp= Setting::Instance().config.getParam(JSNAME(Setting::ServerIp));
        ui->ipComboBox->addItem(serverIp);
    }
}
